package com.sunsharing.common.config;

import com.sunsharing.common.Constant;
import com.sunsharing.common.anno.AnoClassCretator;
import com.sunsharing.common.anno.AnoClassCretator;
import com.sunsharing.common.register.Register;
import com.sunsharing.common.utils.IOUtils;
import com.sunsharing.common.utils.StringUtils;
import org.apache.log4j.Logger;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;

import java.io.File;
import java.io.FileInputStream;
import java.net.URLDecoder;
import java.util.*;

/**
 * Created with IntelliJ IDEA.
 * User: criss
 * Date: 13-4-5
 * Time: 上午11:23
 * To change this template use File | Settings | File Templates.
 */
public class Config {

    Logger logger = Logger.getLogger(Config.class);
    /**命名规则domain.name*/
    String nodeId;

    String domain;

    Register register = (Register) AnoClassCretator.getInstance().
            createObject(Register.class, Constant.REGIEST_XML);

    private Config()
    {

    }
    private static Config config = null;

    public static Config getInstance()
    {
        if(config==null)
        {
            config = new Config();
            config.init();
        }
        return config;
    }

    private void init()
    {
        try
        {
            String path = StringUtils.getClassPath();
            File temp = new File(path+"config.xml");
            String xml = IOUtils.readContent(temp);
            Document doc = DocumentHelper.parseText(xml);
            Element  water = doc.getRootElement();
            nodeId = water.element("node_id").getTextTrim();
            if(nodeId.indexOf(".")!=-1)
            {
                domain = nodeId.substring(0,nodeId.indexOf("."));
            }else
            {
                domain = "default";
            }

            register.load();

        }catch (Exception e)
        {
            logger.error("加载配置文件失败",e);
            throw new RuntimeException("获取配置文件出错",e);
        }
    }



    public String getNodeId() {
        return nodeId;
    }

    public void setNodeId(String nodeId) {
        this.nodeId = nodeId;
    }

    public String getDomain() {
        return domain;
    }

    public void setDomain(String domain) {
        this.domain = domain;
    }

    public Register getRegister() {
        return register;
    }

    public void setRegister(Register register) {
        this.register = register;
    }

    public List<ChannelModel> getMyChannelModel()
    {
        List<NodeModel> nodes = register.getNodes();
        for(NodeModel n:nodes)
        {
            if(n.nodeId.equals(nodeId))
            {
                return n.channelModels;
            }
        }
        return new ArrayList<ChannelModel>();
    }
    public NodeModel getNodeModelByNodeId(String nodeId)
    {
        List<NodeModel> nodes = register.getNodes();
        for(NodeModel n:nodes)
        {
            if(n.nodeId.equals(nodeId))
            {
                return n;
            }
        }
        return null;
    }

    public List<NodeModel> getNodesByServiceName(String serviceName)
    {
        List<NodeModel> nodes = new ArrayList<NodeModel>();
        List<ServiceModel> serviceModels = register.getRegisterModel().services;
        for(ServiceModel service:serviceModels)
        {
            if(service.name.equals(serviceName))
            {
                List<WsdlModel> wsdls = service.wsdlList;
                for(WsdlModel w:wsdls)
                {
                    NodeModel tmp = register.getRegisterModel().searchNodeById(w.nodeId);
                    if(!nodes.contains(tmp))
                    {
                        nodes.add(tmp);
                    }
                }
            }
        }
        return nodes;
    }

    public boolean isflowService(String serverName)
    {
        List<ServiceModel> serviceModels = register.getRegisterModel().services;
        for(ServiceModel service:serviceModels)
        {
            if( service.name.equals(serverName) && service instanceof FlowModel)
            {
                return true;
            }
        }
        return false;
    }

    public boolean isByClient(String fromNode,String toNode)
    {
        List<ChannelModel> channelModels = new ArrayList<ChannelModel>();
        List<RouterModel> routers = register.getRouters();
        for(RouterModel route:routers)
        {
            if(route.fromNode.nodeId.equals(fromNode) && route.toNode.nodeId.equals(toNode) )
            {
                return false;
            }else if(route.fromNode.nodeId.equals(toNode) && route.toNode.nodeId.equals(fromNode) &&
                route.isTwoWay)
            {
                if(route.byClient)
                {
                    return true;
                } else
                {
                    return false;
                }
            }
        }
        return false;
    }

    public List<ChannelModel> getNoByClientChannelModel(String fromNode,String toNode)
    {
        List<ChannelModel> channelModels = new ArrayList<ChannelModel>();
        List<RouterModel> routers = register.getRouters();
        for(RouterModel route:routers)
        {
            if(route.fromNode.nodeId.equals(fromNode) && route.toNode.nodeId.equals(toNode))
            {
                    //如果是主动连接
                addModel(route.fromPro,toNode,channelModels);
             }
            if(route.fromNode.nodeId.equals(toNode) && route.toNode.nodeId.equals(fromNode) &&
                    route.isTwoWay && route.byClient==false)
            {
                //不处理反向连接
                addModel(route.toPro,toNode,channelModels);
            }
        }
        return channelModels;
    }

    private void addModel(String pro,String nodeId,List<ChannelModel> channelModels)
    {
        for(NodeModel node:register.getNodes())
        {
            if(node.nodeId.equals(nodeId))
            {
                for(ChannelModel cm:node.channelModels)
                {
                    if(StringUtils.isBlank(pro))
                    {
                        if(cm.type.equals(Constant.PROTOCOL_MINA)
                                || cm.type.equals(Constant.PROTOCOL_NETTY))
                            channelModels.add(cm);
                    }else
                    {
                        if(cm.type.equals(pro))
                        {
                            channelModels.add(cm);
                        }
                    }
                }
            }
        }
    }

    public ServiceModel getServiceModelByName(String serviceName)
    {
        List<ServiceModel> list = register.getServiceModel();
        for(ServiceModel model:list)
        {
            if(model.name.equals(serviceName))
            {
                return model;
            }
        }
        return null;
    }
}
